package com.kecheng.servermonitor.config.task;

import com.fasterxml.jackson.databind.JsonNode;
import com.kecheng.servermonitor.entity.MonitorProperties;
import com.kecheng.servermonitor.entity.ServiceStatus;
import com.kecheng.servermonitor.entity.StatusReportRequest;
import com.kecheng.servermonitor.entity.TaskProperties;
import com.kecheng.servermonitor.util.SystemMonitorUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;

@Component
@RequiredArgsConstructor
public class ServiceMonitorTask {
    private final MonitorProperties properties;
    @Autowired
    private TaskProperties taskProperties;
    private final RestTemplate restTemplate = new RestTemplate();
    @Value("${email}")
    private String email;
    @Value("${jarPath}")
    private String path;
    // 用于记录正在启动的服务，防止重复启动
    private final Set<String> startingServices = ConcurrentHashMap.newKeySet();

    @Scheduled(fixedDelay = 2000) // 每 10 秒执行一次
    public void monitorServices() {

        //只要满足不是客户端或定时任务未启用这两个条件之一，就直接 return 跳过执行。
        if (!taskProperties.isClient() || !taskProperties.getScheduling().isEnabled()) {
            return;
        }
        List<ServiceStatus> results = new ArrayList<>();
        for (String service : properties.getNacos().getServices()) {
            boolean healthy = isServiceHealthy(service);
            String status = healthy ? "正常" : "离线";
//            if (!healthy) {
//                if (startingServices.contains(service)) {
//                    System.out.println("服务 " + service + " 正在启动中，跳过重复启动");
//                    return;
//                } else {
//                    try {
//                        String javaServerName = service + ".jar";
//                        File jarDirectory = new File(path);
//                        File jarFile = new File(jarDirectory, javaServerName);
//                        if (!jarFile.exists()) {
//                            System.err.println("JAR文件不存在: " + jarFile.getAbsolutePath());
//                            return;
//                        }
//                        System.out.println("开始异步启动服务: " + service);
//                        startingServices.add(service);
//                        // 使用 CompletableFuture 异步执行
//                        CompletableFuture.runAsync(() -> {
//                            try {
//                                ProcessBuilder pb = new ProcessBuilder("java", "-jar", javaServerName, "--spring.profiles.active=beta");
//                                pb.directory(jarDirectory);
//                                pb.inheritIO();
//                                Process process = pb.start();
//                                int exitCode = process.waitFor();
//                                System.out.println("服务 " + service + " 已退出，代码：" + exitCode);
//                            } catch (Exception e) {
//                                System.err.println("服务 " + service + " 启动失败: " + e.getMessage());
//                            } finally {
//                                startingServices.remove(service);
//                            }
//                        });
//                    } catch (Exception e) {
//                        System.out.println(service + "服务重启准备失败！" + e.getMessage());
//                        startingServices.remove(service);
//                    }
//                }
//            }
            System.out.println("服务：" + service + "的健康状态为：" + status);
            results.add(new ServiceStatus(service, healthy));
        }
        sendHeartbeat(results);
    }

    private boolean isServiceHealthy(String serviceName) {
        try {
            String url = String.format(
                    "%s/nacos/v1/ns/instance/list?serviceName=%s&namespaceId=%s",
                    properties.getNacos().getServer(),
                    serviceName,
                    properties.getNacos().getNamespace()
            );

            ResponseEntity<JsonNode> response = restTemplate.getForEntity(url, JsonNode.class);
            if (response.getStatusCode().is2xxSuccessful()) {
                JsonNode hosts = response.getBody().get("hosts");
                if (hosts != null && hosts.isArray()) {
                    for (JsonNode host : hosts) {
                        if (host.get("healthy").asBoolean(false)) {
                            return true;
                        }
                    }
                }
            }
        } catch (Exception ex) {
            System.err.println("检查服务 " + serviceName + " 失败: " + ex.getMessage());
        }
        return false;
    }


    private void sendHeartbeat(List<ServiceStatus> statusList) {

        // 构造请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("client-id", encodeClientId(properties.getClientId()));
        headers.add("email", email);

        // 构造请求体
        StatusReportRequest statusReportRequest = buildStatusReportRequest(statusList);
        HttpEntity<StatusReportRequest> entity = new HttpEntity<>(statusReportRequest, headers);

        // 异步上报（服务端 + 大屏）
        asyncPost(properties.getReportUrl(), entity, "服务端");
        asyncPost(properties.getReportUrlFront(), entity, "大屏接口");

        // 控制台输出
        printHeartbeatLog(statusList);
    }


    private String encodeClientId(String clientId) {
        try {
            return URLEncoder.encode(clientId, StandardCharsets.UTF_8.name());
        } catch (Exception e) {
            System.out.println("client-id 编码失败，使用原始值: " + clientId);
            return clientId;
        }
    }

    private StatusReportRequest buildStatusReportRequest(List<ServiceStatus> statusList) {
        StatusReportRequest req = new StatusReportRequest();
        req.setCpuUsage(SystemMonitorUtil.getCpuUsageWithOshi());
        req.setMemoryUsage(SystemMonitorUtil.getMemoryUsage());
        req.setDiskUsage(SystemMonitorUtil.getDiskUsage());
        req.setServiceStatuses(statusList);
        return req;
    }

    private void asyncPost(String url, HttpEntity<StatusReportRequest> entity, String targetDesc) {
        CompletableFuture.runAsync(() -> {
            try {
                restTemplate.postForEntity(url, entity, String.class);
            } catch (Exception ex) {
                System.err.println("发送到" + targetDesc + "失败: " + ex.getMessage());
            }
        });
    }

    private void printHeartbeatLog(List<ServiceStatus> statusList) {
        String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.out.println(currentTime + " 已上报心跳（客户端: " + properties.getClientId() + "）：" + statusList);
    }


}
